﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using AR.Drone.Client.Command;
using AR.Drone.Client.Configuration;

namespace isDrone
{
    public partial class SettingForm : Form
    {
        private Settings _settings;
        private ISDrone _drone;
        public SettingForm(ISDrone drone)
        {
            InitializeComponent();
            _drone = drone;
        }

        public new void Update()
        {

            Task<Settings> configurationTask = _drone.DroneClient.GetConfigurationTask();
            configurationTask.ContinueWith(delegate(Task<Settings> task)
            {
                if (task.Exception != null)
                {
                    Trace.TraceWarning("Get configuration task is faulted with exception: {0}",
                        task.Exception.InnerException.Message);
                    return;
                }

                _settings = task.Result;
                show();
            });
            configurationTask.Start();



            //  ConfigurationAcquisition t = new ConfigurationAcquisition(_drone.DroneClient);
            //_settings=  t.GetConfiguration();

            //_drone.DroneClient.AckControlAndWaitForConfirmation();
            //_drone.DroneClient.Send(new ConfigIdsCommand("12345678", "12345678", "12345678"));

        }



        private void button2_Click(object sender, EventArgs e)
        {
            Update();
        }



        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            label2.Text = Math.Round((trackBar1.Value * 0.3)) + "гр.";

        }

        private void trackBar6_Scroll(object sender, EventArgs e)
        {
            label12.Text = Math.Round((trackBar6.Value *0.3)) + "гр";
        }

        private void trackBar11_Scroll(object sender, EventArgs e)
        {
            label22.Text = Math.Round((trackBar11.Value * 1.8)) + "гр/с";
        }

        private void trackBar9_Scroll(object sender, EventArgs e)
        {
            label18.Text = Math.Round((trackBar9.Value * 1.8)) + "гр/с.";
        }

        private void trackBar8_Scroll_1(object sender, EventArgs e)
        {
label16.Text = Math.Round((trackBar8.Value * 1.8) + 20) + "см/с";
        }

        private void trackBar7_Scroll(object sender, EventArgs e)
        {
            label14.Text = Math.Round((trackBar7.Value * 1.8) + 20) + "см/с";
        }

        private void trackBar3_Scroll(object sender, EventArgs e)
        {
            label6.Text = trackBar3.Value  + "см";
        }

        private void trackBar4_Scroll(object sender, EventArgs e)
        {
            label8.Text = Math.Round(trackBar4.Value * 0.45 + 5)+"м.";
        }

        private void panel6_Paint(object sender, PaintEventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            button2.Enabled = false;
                if (_settings == null) _settings = new Settings();
                Settings settings = _settings;

                    // set new session, application and profile
                    _drone.DroneClient.AckControlAndWaitForConfirmation(); // wait for the control confirmation
          
                    settings.Custom.SessionId = "ad1efdac";
                    _drone.DroneClient.Send(settings);

                    _drone.DroneClient.AckControlAndWaitForConfirmation();

                    settings.Custom.ProfileId = "992f7f4f";
                    _drone.DroneClient.Send(settings);

                    _drone.DroneClient.AckControlAndWaitForConfirmation();

                    settings.Custom.ApplicationId = "510acf97";
                    _drone.DroneClient.Send(settings);

                    _drone.DroneClient.AckControlAndWaitForConfirmation();

                    settings.Custom.ProfileDescription = textBox3.Text;
                    _drone.DroneClient.Send(settings);

                    _drone.DroneClient.AckControlAndWaitForConfirmation();

                    settings.Custom.ApplicationDescription = textBox2.Text;
                    _drone.DroneClient.Send(settings);

                    _drone.DroneClient.AckControlAndWaitForConfirmation();

                    settings.Custom.SessionDescription = textBox4.Text;
                    _drone.DroneClient.Send(settings);
                    _drone.DroneClient.AckControlAndWaitForConfirmation();
            _settings.General.NavdataDemo = true;
                _settings.Control.EulerAngleMax =radioButton5.Checked? trackBar6.Value / 100.0 * (Math.PI / 6):trackBar1.Value / 100.0 * (Math.PI / 6);
                _settings.Control.IndoorEulerAngleMax = trackBar1.Value / 100.0 * (Math.PI / 6);
                _settings.Control.OutdoorEulerAngleMax = trackBar6.Value / 100.0 * (Math.PI / 6);
                _drone.DroneClient.Send(settings);
                _drone.DroneClient.AckControlAndWaitForConfirmation();

                _settings.Control.ControlYaw = radioButton5.Checked ? trackBar11.Value / 100.0 * (Math.PI) : trackBar9.Value / 100.0 * (Math.PI);
              
                  _settings.Control.IndoorControlYaw = trackBar9.Value / 100.0 * (Math.PI);
                _settings.Control.OutdoorControlYaw = trackBar11.Value / 100.0 * (Math.PI);
                _drone.DroneClient.Send(settings);
                _drone.DroneClient.AckControlAndWaitForConfirmation();

                _settings.Control.ControlVzMax = radioButton5.Checked ? trackBar7.Value / 100.0 * 1800 + 200 : trackBar8.Value / 100.0 * 1800 + 200;
                _settings.Control.IndoorControlVzMax = trackBar8.Value / 100.0 * 1800 + 200;
                _settings.Control.OutdoorControlVzMax = trackBar7.Value / 100.0 * 1800 + 200;
                _drone.DroneClient.Send(settings);
                _drone.DroneClient.AckControlAndWaitForConfirmation();

                settings.Control.AltitudeMin = trackBar3.Value;
                settings.Control.AltitudeMax = trackBar4.Value*450 + 5000;
                settings.Control.Outdoor = radioButton5.Checked;
                settings.Control.FlightWithoutShell = radioButton8.Checked;
                _drone.DroneClient.Send(settings);
                _drone.DroneClient.AckControlAndWaitForConfirmation();

            settings.Network.SsidSinglePlayer = textBox1.Text;
            _settings.Video.Codec = (VideoCodecType)(Enum.Parse(typeof(VideoCodecType), comboBox1.SelectedItem.ToString()));
          _settings.Video.Bitrate=Convert.ToInt32(  textBox5.Text) ;
          _settings.Video.MaxBitrate = Convert.ToInt32(textBox6.Text);
          _settings.Video.BitrateCtrlMode = (VideoBitrateControlMode)(Enum.Parse(typeof(VideoBitrateControlMode), comboBox2.SelectedItem.ToString()));
            _settings.Video.OnUsb = checkBox1.Checked;
            _drone.DroneClient.Send(settings);
                _drone.DroneClient.AckControlAndWaitForConfirmation();

                button2.Enabled = true;
                button1.Enabled = true;

         
          
        }

        delegate void SetCashCallback();

        public void show()
        {
            if (tabControl2.InvokeRequired && tabControl2.InvokeRequired)
            {
                SetCashCallback d = show;
                Invoke(d);
            }
            else
            {

                if (_settings != null)
                {
                    try
                    {
                        label4.Text = Math.Round(_settings.Control.EulerAngleMax*180/Math.PI) + "гр.";

                        trackBar3.Value = _settings.Control.AltitudeMin;
                        label6.Text = _settings.Control.AltitudeMin + "см";

                        trackBar4.Value = ((_settings.Control.AltitudeMax - 5000)/450);
                        label8.Text = _settings.Control.AltitudeMax/100 + "м";

                        label10.Text = Convert.ToInt32(_settings.Control.ControlVzMax/10) + "см/с";

                        label20.Text = Math.Round(_settings.Control.ControlYaw*180/Math.PI) + "гр/c";
                        if (_settings.Control.Outdoor)
                            radioButton5.Checked = true;
                        else
                            radioButton6.Checked = true;

                        if (_settings.Control.FlightWithoutShell)
                            radioButton8.Checked = true;
                        else
                            radioButton7.Checked = true;

                        trackBar1.Value = Convert.ToInt32(_settings.Control.IndoorEulerAngleMax*100.0/(Math.PI/6));
                        label2.Text = Math.Round(_settings.Control.IndoorEulerAngleMax*180/Math.PI) + "гр.";

                        trackBar8.Value = Convert.ToInt32((_settings.Control.IndoorControlVzMax - 200)/18);
                        label16.Text = Convert.ToInt32(_settings.Control.IndoorControlVzMax/10) + "см/с";

                        trackBar9.Value = Math.Min(Convert.ToInt32(_settings.Control.IndoorControlYaw*100.0/(Math.PI)),
                            100);
                        label18.Text = Math.Round(_settings.Control.IndoorControlYaw*180/Math.PI) + "гр/c";

                        trackBar6.Value = Convert.ToInt32(_settings.Control.OutdoorEulerAngleMax*100.0/(Math.PI/6));
                        label12.Text = Math.Round(_settings.Control.OutdoorEulerAngleMax*180/Math.PI) + "гр.";

                        trackBar7.Value = Convert.ToInt32((_settings.Control.OutdoorControlVzMax - 200)/18);
                        label14.Text = Convert.ToInt32(_settings.Control.OutdoorControlVzMax/10) + "см/с";

                        trackBar11.Value = Math.Min(
                            Convert.ToInt32(_settings.Control.OutdoorControlYaw*100.0/(Math.PI)),
                            100);
                        label22.Text = Math.Round(_settings.Control.OutdoorControlYaw*180/Math.PI) + "гр/c";
                        
                        textBox1.Text = _settings.Network.SsidSinglePlayer;
                        comboBox1.DataSource = Enum.GetValues(typeof (VideoCodecType));
                        comboBox1.SelectedItem = _settings.Video.Codec;
                      
                        textBox2.Text = _settings.Custom.ApplicationDescription;
                        textBox3.Text = _settings.Custom.ProfileDescription;
                        textBox4.Text = _settings.Custom.SessionDescription;
                        textBox5.Text = _settings.Video.Bitrate.ToString();
                        textBox6.Text = _settings.Video.MaxBitrate.ToString();
                       checkBox1.Checked =_settings.Video.OnUsb;
                        comboBox2.DataSource = Enum.GetValues(typeof(VideoBitrateControlMode));
                        comboBox2.SelectedItem = _settings.Video.BitrateCtrlMode;

                        TreeNode node =GetOrCreate( tvInfo.Nodes,"Настрйоки");
                        if (_settings != null) DumpBranch(node.Nodes, _settings);
                    }
                    catch
                    {
                    }
                }

            }
        }
        private void DumpBranch(TreeNodeCollection nodes, object o)
        {
            Type type = o.GetType();

            foreach (FieldInfo fieldInfo in type.GetFields())
            {
                TreeNode node = GetOrCreate(nodes, fieldInfo.Name);
                object value = fieldInfo.GetValue(o);

                DumpValue(fieldInfo.FieldType, node, value);
            }

            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                try
                {
                    TreeNode node = GetOrCreate(nodes,propertyInfo.Name);
                    object value = propertyInfo.GetValue(o, null);

                    DumpValue(propertyInfo.PropertyType, node, value);
                }
                catch
                {

                }
            }
        }

        public  TreeNode GetOrCreate( TreeNodeCollection nodes, string key)
        {
            if (nodes.ContainsKey(key) == false)
                return nodes.Add(key, key);
            return nodes[key];
        }
        private void DumpValue(Type type, TreeNode node, object value)
        {
            if (value == null)
                node.Text = node.Name + ": null";
            else
            {
                if (type.Namespace.StartsWith("System") || type.IsEnum)
                    node.Text = node.Name + ": " + value;
                else
                    DumpBranch(node.Nodes, value);
            }
        }


        private void button3_Click(object sender, EventArgs e)
            {

                show();

            }

        private void button3_Click_1(object sender, EventArgs e)
        {
            show();
        }

        private void button4_Click(object sender, EventArgs e)
        {
          
            if (_settings == null) _settings = new Settings();
            Settings settings = _settings;

          
                // set new session, application and profile
                _drone.DroneClient.AckControlAndWaitForConfirmation(); // wait for the control confirmation

                settings.Custom.SessionId = "ad1efdac";
                _drone.DroneClient.Send(settings);

                _drone.DroneClient.AckControlAndWaitForConfirmation();

                settings.Custom.ProfileId = "992f7f4f";
                _drone.DroneClient.Send(settings);

                _drone.DroneClient.AckControlAndWaitForConfirmation();

                settings.Custom.ApplicationId = "510acf97";
                _drone.DroneClient.Send(settings);

                _drone.DroneClient.AckControlAndWaitForConfirmation();
  
        }
    }
}
